package cn.com.nes.site.listener;

import cn.com.nes.site.entity.vo.NullVO;
import cn.com.nes.site.entity.vo.project.ImportGovernmentalCustomerArchiveVO;
import cn.com.nes.site.service.logs.ImportLogsService;
import cn.com.nes.site.service.system.excel.ExcelConsumer;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.LinkedList;

/**
 * 公共excel监听
 *  consumer的基类需要继承ExcelConsumer消费接口
 *
 * @Author: ShenWei
 * @Date: 2024/05/07/14:45
 */
@Slf4j
public class ExcelListener<T> implements ReadListener<T> {

    // 结果集
    private final LinkedList<T> cachedDataList = new LinkedList<>();

    // 入参VO
    private NullVO vo;

    // 导入文件的总条数
    private Integer rowNumber;

    // 导入日志服务
    private ImportLogsService importLogsService;

    // 数据消费者
    private final ExcelConsumer<T> consumer;

    // 默认每满200条进行一次后续操作
    @Setter
    private int batchCount = 5000;

    // 记录推送数据次数
    @Setter
    private int pushCount = 0;

    // 舍弃前面的行数,前面几行不要
    @Setter
    private int removeStart = 0;

    // 舍弃后面的行数,后面几行不要
    @Setter
    private int removeEnd = 0;

    public ExcelListener(NullVO vo, ExcelConsumer<T> consumer, ImportLogsService importLogsService) {
        this.vo = vo;
        this.consumer = consumer;
        this.importLogsService = importLogsService;
    }

    @Override
    public void invoke(T data, AnalysisContext analysisContext) {
        handleImportDataRowCount(analysisContext);
        cachedDataList.add(data);
        // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (cachedDataList.size() >= batchCount) {
            if (pushCount == 0 && removeStart > 0) {
                // 第一次推送数据,去掉前REMOVE_START行
                cachedDataList.subList(0, removeStart - 1).clear();
            }
            consumer.receive(vo, cachedDataList);
            cachedDataList.clear();
            pushCount++;
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//        // 插入错误日志主表条数
//        importLogsService.insertCustomerInfoData((ImportGovernmentalCustomerArchiveVO)vo,rowNumber);
        //将最后一次的数据处理掉
        if (!cachedDataList.isEmpty()) {
            if (pushCount == 0 && removeStart > 0) {
                // 第一次推送数据,去掉前REMOVE_START行
                cachedDataList.subList(0, removeStart - 1).clear();
            }
            consumer.receive(vo, cachedDataList);
        }
        log.info("解析excel数据完成");
    }

    // 处理导入总行数
    private void handleImportDataRowCount(AnalysisContext analysisContext) {
        rowNumber = analysisContext.readSheetHolder().getApproximateTotalRowNumber() - removeStart;
        ImportGovernmentalCustomerArchiveVO realVO = (ImportGovernmentalCustomerArchiveVO) vo;
        realVO.setImportDataRowCount(rowNumber);
        log.info("导入总行数:{}", rowNumber);
    }
}
